package com.ddm.service.impl.vxImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ddm.context.BaseContext;
import com.ddm.dto.vxDTO.QuestionAnalysis;
import com.ddm.dto.vxDTO.QuestionDTO;
import com.ddm.dto.vxDTO.StandardExamDTO;
import com.ddm.entity.vxEntity.Announcement;
import com.ddm.entity.vxEntity.BonusPoints;
import com.ddm.entity.vxEntity.Question;
import com.ddm.entity.vxEntity.User;
import com.ddm.entity.vxEntity.WrongQuestion;
import com.ddm.enumeration.AnnouncementType;
import com.ddm.exception.DataErrorException;
import com.ddm.mapper.AnnouncementMapper;
import com.ddm.mapper.BonusPointMapper;
import com.ddm.mapper.QuetsionsMapper;
import com.ddm.mapper.UserMapper;
import com.ddm.mapper.WrongQuestionMapper;
import com.ddm.service.vxService.AnnouncementService;
import com.ddm.service.vxService.BonusPointService;
import com.ddm.service.vxService.WrongQuestionService;
import com.ddm.utils.BeanCopyUtil;
import com.ddm.vo.vxVo.BonusPointsStatisticsVO;
import com.ddm.vo.vxVo.BonusPointsVO;
import com.ddm.vo.vxVo.ContestStatisticsVO;
import com.ddm.vo.vxVo.PointsDistributionVO;
import com.ddm.vo.vxVo.UserPointsRankVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BonusPointsImpl   extends ServiceImpl<BonusPointMapper, BonusPoints> implements BonusPointService {
    @Autowired
    BonusPointMapper bonusPointMapper;
    @Autowired
    QuetsionsMapper quetsionsMapper;
    @Autowired
    WrongQuestionMapper wrongQuestionMapper;
    @Autowired
    WrongQuestionService wrongQuestionService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    AnnouncementMapper announcementMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BonusPointsVO submitStandardExam(Long standardId, List<StandardExamDTO> standardExamDTOS) {
        Long userId = BaseContext.getCurrentId();
        ArrayList<WrongQuestion> wrongQuestions = new ArrayList<>();
        LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Question::getStandardId , standardId);
        List<Question> questions = quetsionsMapper.selectList(wrapper);
        List<QuestionAnalysis> questionAnalyses = BeanCopyUtil.BeanCopyList(questions, QuestionAnalysis.class);
        for (int i = 0; i < questions.size(); i++) {
            Question question = questions.get(i);
            QuestionAnalysis analysis = questionAnalyses.get(i);
            analysis.setQuestionId(question.getId()); // 手动赋值
            analysis.setCorrectAnswer(question.getAnswer()); // 设置正确答案
        }
        HashMap<Long, Boolean> isCorrectMap = new HashMap<>();
        List<Long> questionIds = standardExamDTOS.stream().map(StandardExamDTO::getQuestionId).collect(Collectors.toList());
        Set<Long> questionIdSet = new HashSet<>(questionIds);
        List<Question> questionList = questions.stream().filter(question -> questionIdSet.contains(question.getId())).collect(Collectors.toList());
        int point = 0;
        HashMap<Long, String> answerMap = new HashMap<>();
        for (Question question : questionList) {
            String answer = question.getAnswer();
            answerMap.put(question.getId(),answer);
        }

        for (StandardExamDTO standardExamDTO : standardExamDTOS) {
            String answer = answerMap.get(standardExamDTO.getQuestionId());
            if (answer == null){
                throw new DataErrorException("题目不存在");
            }
            boolean isCorrect = normalizeAnswer(standardExamDTO.getUserAnswer()).equals(normalizeAnswer(answer));
            isCorrectMap.put(standardExamDTO.getQuestionId(), isCorrect);
            if (isCorrect){
                point +=1;
            }else {
                //录入错题表
                WrongQuestion wrongQuestion = WrongQuestion.builder().questionId(standardExamDTO.getQuestionId()).userId(userId).build();
                LambdaQueryWrapper<WrongQuestion> query = new LambdaQueryWrapper<>();
                query.eq(WrongQuestion::getQuestionId,standardExamDTO.getQuestionId()).eq(WrongQuestion::getUserId,userId);
                if (wrongQuestionMapper.selectOne(query)==null){
                    wrongQuestions.add(wrongQuestion);
                }
                }
            }
        for (QuestionAnalysis questionAnalysis : questionAnalyses) {
            Boolean isCorrect = isCorrectMap.get(questionAnalysis.getQuestionId());
            questionAnalysis.setIsCorrect(isCorrect != null ? isCorrect : false);
            
            // 设置用户选择的答案
            StandardExamDTO userAnswer = standardExamDTOS.stream()
                    .filter(dto -> dto.getQuestionId().equals(questionAnalysis.getQuestionId()))
                    .findFirst()
                    .orElse(null);
            questionAnalysis.setUserAnswer(userAnswer != null ? userAnswer.getUserAnswer() : "");
        }
        wrongQuestionService.saveBatch(wrongQuestions);
        BonusPoints bonusPoints = new BonusPoints();
        LambdaQueryWrapper<BonusPoints> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BonusPoints::getUserId,userId);
        BonusPoints exitBonusPoint = bonusPointMapper.selectOne(queryWrapper);
        bonusPoints.setPoints(point);
        bonusPoints.setUserId(userId);
        if (exitBonusPoint !=null){
            bonusPointMapper.update(bonusPoints,queryWrapper);
        }else {
            bonusPointMapper.insert(bonusPoints);
        }
        BonusPointsVO bonusPointsVO = BeanCopyUtil.BeanCopy(bonusPoints, BonusPointsVO.class);
        bonusPointsVO.setQuestionList(questionAnalyses);
        return bonusPointsVO;
    }

    @Override
    public BonusPointsStatisticsVO getTotalPointsStatistics() {
        // 1. 查询所有积分记录
        List<BonusPoints> allBonusPoints = bonusPointMapper.selectList(null);
        
        // 2. 查询所有用户数量
        int totalUsers = userMapper.selectCount(null);
        
        // 3. 计算基础统计信息
        int totalPoints = allBonusPoints.stream()
                .mapToInt(BonusPoints::getPoints)
                .sum();
        
        int usersWithPoints = allBonusPoints.size();
        
        double averagePoints = usersWithPoints > 0 ? 
                (double) totalPoints / usersWithPoints : 0.0;
        
        int maxPoints = allBonusPoints.stream()
                .mapToInt(BonusPoints::getPoints)
                .max()
                .orElse(0);
        
        int minPoints = allBonusPoints.stream()
                .mapToInt(BonusPoints::getPoints)
                .min()
                .orElse(0);
        
        // 4. 生成积分排行榜（全部用户）
        List<UserPointsRankVO> topRanking = allBonusPoints.stream()
                .sorted((a, b) -> Integer.compare(b.getPoints(), a.getPoints()))
                .map(bonusPoint -> {
                    UserPointsRankVO rankVO = new UserPointsRankVO();
                    rankVO.setUserId(bonusPoint.getUserId());
                    rankVO.setPoints(bonusPoint.getPoints());
                    
                    // 查询用户名
                    User user = userMapper.selectById(bonusPoint.getUserId());
                    rankVO.setUserName(user != null ? user.getUserName() : "未知用户");
                    
                    // 格式化更新时间
                    if (bonusPoint.getUpdateTime() != null) {
                        rankVO.setUpdateTime(bonusPoint.getUpdateTime()
                                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    }
                    
                    return rankVO;
                })
                .collect(Collectors.toList());
        
        // 设置排名
        for (int i = 0; i < topRanking.size(); i++) {
            topRanking.get(i).setRank(i + 1);
        }
        
        // 5. 生成积分分布统计
        final int finalTotalUsers = totalUsers;
        List<PointsDistributionVO> pointsDistribution = generatePointsDistribution(allBonusPoints, finalTotalUsers);
        
        // 6. 构建返回结果
        BonusPointsStatisticsVO statisticsVO = new BonusPointsStatisticsVO();
        statisticsVO.setTotalPoints(totalPoints);
        statisticsVO.setTotalUsers(totalUsers);
        statisticsVO.setUsersWithPoints(usersWithPoints);
        statisticsVO.setAveragePoints(Math.round(averagePoints * 100.0) / 100.0); // 保留两位小数
        statisticsVO.setMaxPoints(maxPoints);
        statisticsVO.setMinPoints(minPoints);
        statisticsVO.setTopRanking(topRanking);
        statisticsVO.setPointsDistribution(pointsDistribution);
        
        return statisticsVO;
    }

    /**
     * 生成积分分布统计
     */
    private List<PointsDistributionVO> generatePointsDistribution(List<BonusPoints> allBonusPoints, int totalUsers) {
        List<PointsDistributionVO> distribution = new ArrayList<>();
        
        // 定义积分范围
        int[] ranges = {0, 10, 20, 30, 50, 100, Integer.MAX_VALUE};
        String[] rangeLabels = {"0-10", "11-20", "21-30", "31-50", "51-100", "100+"};
        
        for (int i = 0; i < ranges.length - 1; i++) {
            final int min = ranges[i];
            final int max = ranges[i + 1];
            final int index = i;
            
            int userCount = (int) allBonusPoints.stream()
                    .filter(bp -> {
                        int points = bp.getPoints();
                        if (index == ranges.length - 2) { // 最后一个范围
                            return points >= min;
                        } else {
                            return points >= min && points < max;
                        }
                    })
                    .count();
            
            PointsDistributionVO distributionVO = new PointsDistributionVO();
            distributionVO.setRange(rangeLabels[i]);
            distributionVO.setUserCount(userCount);
            distributionVO.setPercentage(totalUsers > 0 ? 
                    Math.round((double) userCount / totalUsers * 10000) / 100.0 : 0.0);
            
            distribution.add(distributionVO);
        }
        
        return distribution;
    }

    @Override
    public ContestStatisticsVO getContestStatistics() {
        Long currentUserId = BaseContext.getCurrentId();
        
        // 1. 查询总竞赛数（公告类型为竞赛的数量）
        LambdaQueryWrapper<Announcement> contestWrapper = new LambdaQueryWrapper<>();
        contestWrapper.eq(Announcement::getType, AnnouncementType.COMPETITION);
        int totalContests = announcementMapper.selectCount(contestWrapper);
        
        // 2. 查询参与人数（有积分的用户数量）
        int totalParticipants = bonusPointMapper.selectCount(null);
        
        // 3. 查询我的积分
        LambdaQueryWrapper<BonusPoints> myPointsWrapper = new LambdaQueryWrapper<>();
        myPointsWrapper.eq(BonusPoints::getUserId, currentUserId);
        BonusPoints myBonusPoints = bonusPointMapper.selectOne(myPointsWrapper);
        int myPoints = myBonusPoints != null ? myBonusPoints.getPoints() : 0;
        
        // 4. 查询我的排名
        int myRank = calculateMyRank(currentUserId, myPoints);
        
        // 5. 查询我的用户名
        User currentUser = userMapper.selectById(currentUserId);
        String myUsername = currentUser != null ? currentUser.getUserName() : "未知用户";
        
        // 6. 构建返回结果
        ContestStatisticsVO contestStatisticsVO = new ContestStatisticsVO();
        contestStatisticsVO.setTotalContests(totalContests);
        contestStatisticsVO.setTotalParticipants(totalParticipants);
        contestStatisticsVO.setMyPoints(myPoints);
        contestStatisticsVO.setMyRank(myRank);
        contestStatisticsVO.setMyUsername(myUsername);
        
        return contestStatisticsVO;
    }
    
    /**
     * 计算我的排名
     */
    private int calculateMyRank(Long userId, int myPoints) {
        // 查询所有用户的积分，按积分降序排列
        List<BonusPoints> allBonusPoints = bonusPointMapper.selectList(null);
        
        // 按积分降序排序
        allBonusPoints.sort((a, b) -> Integer.compare(b.getPoints(), a.getPoints()));
        
        // 找到我的排名
        for (int i = 0; i < allBonusPoints.size(); i++) {
            if (allBonusPoints.get(i).getUserId().equals(userId)) {
                return i + 1; // 排名从1开始
            }
        }
        
        // 如果没有找到，说明没有积分记录，排名为参与人数+1
        return allBonusPoints.size() + 1;
    }

    private String normalizeAnswer(String answer) {
        if (answer == null || answer.trim().isEmpty()) {
            return "";
        }
        // 处理空格、大小写并排序
        return Arrays.stream(answer.split(","))
                .map(String::trim)
                .map(String::toUpperCase)
                .sorted()
                .collect(Collectors.joining(","));
    }
}
